/**
 * @brief 常用的一些工具算法或者定义
 * @note 现在这些函数不支持获取多个查询的URL内容
 * @version 0.1
 * @date 2017-2-8
 * @author 宋炜
 */

#ifndef __MISC_H__
#define __MISC_H__

#include <string>
#include <iostream>
/**
 * @brief 获取libuv错误信息
 * @param retcode，libuv操作返回的错误代码
 */
std::string GetUVError(int retcode) ;

/**
 * @brief 解析URL，获取URL的协议部分字符串
 * @note 现在这些函数不支持获取多个查询的URL内容
 * @param url , url字符串呢
 * @retval 返回协议字符串
 */
std::string GetURLProtocol( const std::string& url );

/**
 *@brief 解析URL，获取主机字符串
 *@param url
 *@retval
 */
std::string GetURLHost( const std::string& url );
/**
 *@brief 获取URL路径
 */
std::string GetURLPath( const std::string& url );

/**
 *@brief 获取URL服务器
 */
std::string GetURLService( const std::string& url );

/**
 * @brief 获取URL参数
 */
std::string GetURLParam( const std::string& url );

/**
 *@brief 获取URL查询
 */
std::string GetURLQuery( const std::string& url );

/**
 * @brief 获取URL片段
 */
std::string GetURLFragment( const std::string& url );

/**
 * @brief 输出信息到指定的流
 * @param enable , 是否输出；true执行输出，false放弃输出
 * @param os, 要输出的流
 * @param msg , 要输出的信息
 */
void log_base( bool enable , std::ostream& os, const std::string& msg );
#define LOG( enable , msg )     log_base( enable , std::cerr , msg )

/**
 * @brief 按照行输出信息，也就是完成输出消息后再自动添加一个换行
 */
void logln_base( bool , std::ostream& , const std::string& );
#define LOGLN( enable , msg )   logln_base( enable , std::cerr , msg )

std::string GetNopollError();
/**
 * @brief 16进制字符串和二进制串相互转换函数
 */
size_t str2hex( const std::string& str , uint8_t * data );
size_t hex2str( const char * data , std::string& str );
/**
 * @brief 把字符串转为 hex 压缩格式。
 * @param str , 要转的字符串
 * @param rst , 操作结果。內存应预先分配好
 * @return 成功转化返回true，否则返回false
 */
bool str2hex4bit( const std::string& str , uint8_t * rst );
/**
 * 调试信息数据模块。通过宏定义如果需要编译不带调试信息输出的的版本则去掉__DEBUG__定义就行
 */
#if defined( __DEBUG__ )
    	void dump( const char* data , size_t s );
    	void dump_2( const char* data , size_t s );
	#define __show_line( str ) 								\
		do{ 										 \
			std::cout << __FILE__ << " [ " << __LINE__ << " ] " << str << std::endl; \
		}while(0)
		
	#define __show_line_1( format , ... ) 					\
		do{ 								\
			std::cout << __FILE__ << " [ " << __LINE__  << " ] ";	\
			printf( format , __VA_ARGS__ ); putchar('\n');		\
		}while(0)

	#define __show_line_2() __show_line("")
#else
	#define __show_line( str ) do{}while(0)
	#define __show_line_1( format , ... ) do{}while(0)
	#define __show_line_2() do{}while(0)
#endif
/**
 * 
 */
typedef std::uint64_t hash_t;
constexpr hash_t basis = 0xCBF29CE484222325ull;
constexpr hash_t prime = 0x100000001B3ull;
extern hash_t hash_( char const *str );
extern hash_t hash_( char const *str , size_t len );
/////////////////////////////////////////////////////////////////////////////////////////////////////////
constexpr hash_t hash_compile_time(char const* str, hash_t last_value = basis)
{
    	return *str ? hash_compile_time(str+1, (*str ^ last_value) * prime) : last_value;
}

#endif

